// Decompiled with JetBrains decompiler
// Type: FibMatrix.Config.MetaItemHelper
// Assembly: FMCommon, Version=1.0.8663.21262, Culture=neutral, PublicKeyToken=null
// MVID: 52773074-FB09-4BA0-8FA9-4782D11D6C17
// Assembly location: /Users/mac/work/RiverGame/com.rivergame.fmframework/Runtime/Plugins/FMCommon.dll

using System.Runtime.CompilerServices;

namespace FibMatrix.Config
{
  public class MetaItemHelper
  {
    public const byte VALUE_NULL_FLAG = 128;
    public const byte VALUE_TYPE_MASK = 127;
    private const int FIXED_START_OFFSET = 9;
    private byte[] _buffer;
    private int _totalNum;
    private int _propNum;
    private int _propNameOffset;
    private int _propTypeOffset;
    private int _propRowPosStartOffset;
    private int _propRowAreaStartOffset;
    private int _propAreaLength;
    private int _curRow;
    private int _rowByteLenStartOffset;
    private int _rowStartPos;
    private int _rowValCount;
    private int _rowIndexOrValStartOffset;
    private int _typeByteNums;
    private int _valByteLenArrLength;
    private MetaIdType _idType;

    public MetaItemHelper(byte[] buffer, int offset)
    {
      this._buffer = buffer;
      this._propNameOffset = offset + 9;
      this._idType = (MetaIdType) this._buffer[offset];
      this._totalNum = ConfigFormatUtil.ReadInt32(this._buffer, offset + 1);
      this._propNum = ConfigFormatUtil.ReadInt32(this._buffer, offset + 5);
      this._propTypeOffset = this._propNameOffset + this._propNum * 4;
      this._typeByteNums = this._propNum % 2 == 0 ? this._propNum / 2 : this._propNum / 2 + 1;
      this._propRowPosStartOffset = this._propTypeOffset + this._typeByteNums;
      this._propRowAreaStartOffset = this._propRowPosStartOffset + this._totalNum * 4 + 4;
      this._propAreaLength = ConfigFormatUtil.ReadInt32(this._buffer, this._propRowAreaStartOffset - 4);
      this.MoveToRow(0);
    }

    public void Dispose()
    {
      this._buffer = (byte[]) null;
    }

    public bool hasId
    {
      get
      {
        return (uint) this._idType > 0U;
      }
    }

    public MetaIdType idType
    {
      get
      {
        return this._idType;
      }
    }

    public int rowValCount
    {
      get
      {
        return this._rowValCount;
      }
    }

    public int rowStartPos
    {
      get
      {
        return this._rowStartPos;
      }
    }

    public int currentRow
    {
      get
      {
        return this._curRow;
      }
    }

    public int totalNum
    {
      get
      {
        return this._totalNum;
      }
    }

    public int propNum
    {
      get
      {
        return this._propNum;
      }
    }

    public byte[] buffer
    {
      get
      {
        return this._buffer;
      }
    }

    public int propAreaLength
    {
      get
      {
        return this._propAreaLength;
      }
    }

    public int propRowPosStartOffset
    {
      get
      {
        return this._propRowPosStartOffset;
      }
    }

    public int propRowAreaStartOffset
    {
      get
      {
        return this._propRowAreaStartOffset;
      }
    }

    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public int GetPropNameAt(int col)
    {
      return ConfigFormatUtil.ReadInt32(this._buffer, this._propNameOffset + col * 4);
    }

    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    private void ReadRowInfo()
    {
      this._rowValCount = ConfigFormatUtil.Read7BitEncodedInt(this._buffer, ref this._rowByteLenStartOffset);
      this._valByteLenArrLength = (this._rowValCount & 3) == 0 ? this._rowValCount >> 2 : (this._rowValCount >> 2) + 1;
      this._rowIndexOrValStartOffset = this._rowByteLenStartOffset + this._valByteLenArrLength;
    }

    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public int GetRowStartOffsetAt(int row)
    {
      return ConfigFormatUtil.ReadInt32(this._buffer, this._propRowPosStartOffset + (row << 2)) + this._propRowAreaStartOffset;
    }

    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public void MoveToRow(int row)
    {
      this._curRow = row;
      this._rowStartPos = this._rowByteLenStartOffset = ConfigFormatUtil.ReadInt32(this._buffer, this._propRowPosStartOffset + (row << 2)) + this._propRowAreaStartOffset;
      this.ReadRowInfo();
    }

    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public unsafe MetaSerializeType GetFirstType(byte* bufferPtr)
    {
      return (MetaSerializeType) ((uint) bufferPtr[this._propTypeOffset] & 15U);
    }

    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public unsafe bool GetFirstPropVal(byte* bufferPtr, MetaSerializeType propType, out int val)
    {
      int pos = this._rowByteLenStartOffset + this._valByteLenArrLength;
      byte encodeVal = (byte) ((uint) bufferPtr[this._rowByteLenStartOffset] & 3U);
      byte byteNum = propType == MetaSerializeType.Int || propType == MetaSerializeType.FloatArray || (propType == MetaSerializeType.IntArray || propType == MetaSerializeType.StringArray) ? ConfigFormatUtil.DecodeIntByteLen(encodeVal) : ConfigFormatUtil.DecodeOtherByteLen(encodeVal);
      if (byteNum == (byte) 0)
      {
        val = -1;
        return false;
      }
      val = ConfigFormatUtil.ReadInt32(bufferPtr, ref pos, byteNum);
      return true;
    }

    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public MetaSerializeType GetPropTypeAt(int valIndex)
    {
      byte num = this._buffer[this._propTypeOffset + valIndex / 2];
      return (valIndex & 1) == 0 ? (MetaSerializeType) ((uint) num & 15U) : (MetaSerializeType) ((uint) num >> 4);
    }

    public unsafe void FillAllVals(byte[] types, int[] vals, out int extraDataPos)
    {
      int pos = this._rowByteLenStartOffset + this._valByteLenArrLength;
      fixed (int* numPtr1 = vals)
        fixed (byte* numPtr2 = types)
          fixed (byte* buffers = this._buffer)
          {
            byte* numPtr3 = buffers + this._rowByteLenStartOffset;
            for (int index = 0; index < this._rowValCount; ++index)
            {
              MetaSerializeType metaSerializeType = (MetaSerializeType) ((uint) numPtr2[index] & (uint) sbyte.MaxValue);
              byte encodeVal = (byte) ((int) numPtr3[index >> 2] >> ((index & 3) << 1) & 3);
              byte byteNum = metaSerializeType == MetaSerializeType.Int || metaSerializeType == MetaSerializeType.FloatArray || (metaSerializeType == MetaSerializeType.IntArray || metaSerializeType == MetaSerializeType.StringArray) ? ConfigFormatUtil.DecodeIntByteLen(encodeVal) : ConfigFormatUtil.DecodeOtherByteLen(encodeVal);
              if (byteNum == (byte) 0)
              {
                numPtr1[index] = 0;
                numPtr2[index] = (byte) (metaSerializeType | (MetaSerializeType) 128);
              }
              else
              {
                numPtr1[index] = ConfigFormatUtil.ReadInt32(buffers, ref pos, byteNum);
                numPtr2[index] = (byte) metaSerializeType;
              }
            }
            ConfigFormatUtil.Read7BitEncodedInt(buffers, ref pos);
          }
      extraDataPos = pos;
    }
  }
}
